home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / gnushogi.lha / gnushogi-1.1 / src / util.c < prev    next >
C/C++ Source or Header  |  1993-04-16  |  13KB  |  595 lines

  1. /*
  2.  * util.c - C source for GNU SHOGI
  3.  *
  4.  * Copyright (c) 1993 Matthias Mutz
  5.  *
  6.  * GNU SHOGI is based on GNU CHESS
  7.  *
  8.  * Copyright (c) 1988,1989,1990 John Stanback
  9.  * Copyright (c) 1992 Free Software Foundation
  10.  *
  11.  * This file is part of GNU SHOGI.
  12.  *
  13.  * GNU Shogi is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 1, or (at your option)
  16.  * any later version.
  17.  *
  18.  * GNU Shogi is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with GNU Shogi; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27. #include "gnushogi.h"
  28. unsigned int TTadd = 0;
  29. short int recycle;
  30. extern char mvstr[4][6];
  31.  
  32. #ifdef THINK_C
  33. #include <string.h>
  34. #define bcopy(src,dst,len) memcpy(dst,src,len)
  35. #endif
  36.  
  37. int
  38. parse (FILE * fd, short unsigned int *mv, short int side, char *opening)
  39. {
  40.   register int c, i, r1, r2, c1, c2;
  41.   char s[128];
  42.   char *p;
  43.  
  44.   while ((c = getc (fd)) == ' ' || c == '\n') ;
  45.   i = 0;
  46.   s[0] = (char) c;
  47.   if (c == '!')
  48.     {
  49.       p = opening;
  50.       do
  51.     {
  52.       *p++ = c;
  53.       c = getc (fd);
  54.       if (c == '\n' || c == EOF)
  55.         {
  56.           *p = '\0';
  57.           return 0;
  58.         }
  59.       } while (true);
  60.     }
  61.   while (c != '?' && c != ' ' && c != '\t' && c != '\n' && c != EOF)
  62.     s[++i] = (char) (c = getc (fd));
  63.   s[++i] = '\0';
  64.   if (c == EOF)
  65.     return (-1);
  66.   if (s[0] == '!' || s[0] == ';' || i < 3)
  67.     {
  68.       while (c != '\n' && c != EOF)
  69.     c = getc (fd);
  70.       return (0);
  71.     }
  72.   c1 = '9' - s[0];
  73.   r1 = 'i' - s[1];
  74.   c2 = '9' - s[2];
  75.   r2 = 'i' - s[3];
  76.   *mv = (locn (r1, c1) << 8) | locn (r2, c2);
  77.   if (c == '?')
  78.     {                /* Bad move, not for the program to play */
  79.       *mv |= 0x8000;        /* Flag it ! */
  80.       c = getc (fd);
  81.     }
  82.   return (1);
  83. }
  84.  
  85.  
  86. /*
  87.  * The field of a hashtable is computed as follows:
  88.  *   if sq is on board (< NO_SQUARES) the field gets the value
  89.  *     of the piece on the square sq;
  90.  *   if sq is off board (>= NO_SQUARES) it is a catched figure,
  91.  *     and the field gets the number of catched pieces for
  92.  *     each side.
  93.  */
  94.  
  95.  
  96. inline
  97. unsigned char
  98. CB (short sq)
  99.   register short i = sq;
  100.   if ( i < NO_SQUARES ) {
  101.     return ( (color[i] == white) ? (0x80 | board[i]) : board[i] );
  102.   } else {
  103.     i -= NO_SQUARES;
  104.     return ( (Captured[black][i] << 4) | Captured[white][i] );
  105.   }
  106. }
  107.  
  108.       
  109.  
  110. #if defined DEBUG && defined CACHE                
  111.                           
  112. inline
  113. char
  114. BDpiece(unsigned char p)
  115. {
  116.   unsigned short piece = p & 0x7f;
  117.   if ( piece == no_piece )
  118.     return '-';
  119.   else if ( p & 0x80 )
  120.     return qxx[piece];
  121.   else
  122.     return pxx[piece];
  123. }
  124.  
  125. inline
  126. char
  127. BDpromoted(unsigned char p)
  128. {
  129.   unsigned short piece = p & 0x7f;
  130.   if ( is_promoted[piece] )
  131.     return '+';
  132.   else
  133.     return ' ';
  134. }
  135.  
  136. void
  137. ShowBD(unsigned char bd[])
  138. {
  139.   register short i;
  140.   for ( i = 0; i < PTBLBDSIZE; i++) 
  141.     {                   
  142.     if ( i < NO_SQUARES )
  143.       { 
  144.             printf("%c%c(%c%c) ",
  145.                BDpromoted(bd[i]),BDpiece(bd[i]),
  146.                BDpromoted(CB(i)),BDpiece(CB(i)));
  147.           if ( i % NO_COLS == NO_COLS - 1 )
  148.           printf("\n");
  149.       }
  150.     else
  151.       printf("%2x(%2x) ",bd[i],CB(i));
  152.     };
  153.   printf("\n");
  154. }        
  155.  
  156. #endif
  157.  
  158.  
  159.  
  160. #if ttblsz
  161.  
  162.  
  163.  
  164. int
  165. ProbeTTable (short int side,
  166.          short int depth,
  167.          short int ply,
  168.          short int *alpha,
  169.          short int *beta,
  170.          short int *score)
  171.  
  172. /*
  173.  * Look for the current board position in the transposition table.
  174.  */
  175.  
  176. {
  177.   register struct hashentry *ptbl;
  178.   register /*unsigned*/ short i;  /*to match new type of rehash --tpm*/
  179.  
  180.   ptbl = &ttable[side][hashkey & (ttblsize - 1)];
  181.  
  182.   /* rehash max rehash times */
  183.   for (i = 0; (ptbl->depth) && (ptbl->hashbd != hashbd) && (i < rehash); i++) ptbl++;
  184.   if ((ptbl->depth) && (ptbl->hashbd == hashbd))
  185. /*     ^^^^^^^^^^^^   we can use some informations of the entry even
  186.                       the depth is not large enough */
  187.     {  
  188. #if defined HASHTEST
  189.       for (i = 0; i < PTBLBDSIZE; i++)
  190.     {
  191.       if (ptbl->bd[i] != CB (i))
  192.         {
  193.           HashCol++;
  194. #if defined DEBUG && !defined BAREBONES
  195.           ShowMessage (CP[199]);    /*ttable collision detected*/
  196. #endif
  197.           return(false);
  198.         }
  199.     }
  200. #endif /* HASHTEST */ 
  201.  
  202.  
  203.       PV = SwagHt = ptbl->mv;
  204.       if ((short) ptbl->depth >= depth)
  205.     {
  206. #if !defined BAREBONES
  207.           HashCnt++;
  208. #endif
  209.       if (ptbl->flags & truescore)
  210.         {
  211.           *score = ptbl->score;
  212.           /* adjust *score so moves to mate is from root */
  213.           if (*score > SCORE_LIMIT)
  214.         *score -= ply;
  215.           else if (*score < -SCORE_LIMIT)
  216.         *score += ply;
  217.           *beta = -((SCORE_LIMIT+1000)*2);
  218.         }
  219. #ifdef notdef            /* Never happens! see search */
  220.       else if (ptbl->flags & upperbound)
  221.         {
  222.           if (ptbl->score < *beta)
  223.         *beta = ptbl->score + 1;
  224.         }
  225. #endif
  226.       else if (ptbl->flags & lowerbound)
  227.         {
  228.           if (ptbl->score > *alpha)
  229.         *alpha = ptbl->score - 1;
  230.         }
  231.       return (true);
  232.     }
  233.     }
  234.   return (false);
  235. }
  236.  
  237.  
  238. int
  239. PutInTTable (short int side,
  240.          short int score,
  241.          short int depth,
  242.          short int ply,
  243.          short int alpha,
  244.          short int beta,
  245.          short unsigned int mv)
  246.  
  247. /*
  248.  * Store the current board position in the transposition table.
  249.  */
  250.  
  251. {
  252.   register struct hashentry *ptbl;
  253.   register /*unsigned*/ short i;  /*to match new type of rehash --tpm*/
  254.  
  255.   ptbl = &ttable[side][hashkey & (ttblsize - 1)];
  256.  
  257.   /* rehash max rehash times */
  258.   for (i = 0; ptbl->depth && ptbl->hashbd != hashbd && i < rehash; i++)
  259.     ptbl++;
  260.   if (i == rehash) {
  261. #if !defined BAREBONES
  262.     THashCol++;
  263. #endif
  264.     ptbl -= recycle;}
  265.   if (depth >= (short)ptbl->depth || ptbl->hashbd != hashbd)
  266.     {
  267. #if !defined BAREBONES
  268.       TTadd++;
  269.       HashAdd++; 
  270. #endif
  271.       ptbl->hashbd = hashbd;
  272.       ptbl->depth = (unsigned char) depth;
  273.       /* adjust score so moves to mate is from this ply */
  274.       if (score > SCORE_LIMIT)
  275.     score += ply;
  276.       else if (score < -SCORE_LIMIT)
  277.     score -= ply;
  278.       ptbl->score = score;
  279.       ptbl->mv = mv;
  280. #ifdef DEBUG4
  281.       if (debuglevel & 32)
  282.     {
  283.       algbr (mv >> 8, mv & 0xff, 0);
  284.       printf ("-add-> d=%d s=%d p=%d a=%d b=%d %s\n", depth, score, ply, alpha, beta, mvstr);
  285.     }
  286. #endif
  287. /*#ifdef notdef
  288.       if (score < alpha)
  289.     ptbl->flags = upperbound;
  290.       else
  291. /*#endif /* 0 */
  292.       if (score > beta)
  293.     {
  294.       ptbl->flags = lowerbound;
  295.       score = beta + 1;
  296.     }
  297.       else
  298.     ptbl->flags = truescore;
  299.        
  300. #if defined HASHTEST
  301.       for (i = 0; i < PTBLBDSIZE; i++)
  302.     {
  303.       ptbl->bd[i] = CB (i);
  304.     }
  305. #endif /* HASHTEST */
  306.       return true;
  307.     }
  308.   return false;
  309. }
  310.  
  311.    
  312. static struct hashentry *ttageb, *ttagew;
  313.  
  314. void
  315. ZeroTTable (void)
  316. {
  317.    register struct hashentry *w, *b;
  318.    for ( b=ttable[black], w=ttable[white]; b < &ttable[black][ttblsize]; w++, b++)
  319.      { 
  320.         w->depth = 0; 
  321.         b->depth = 0;
  322.      }
  323.    ttageb = ttable[black]; 
  324.    ttagew = ttable[white];
  325. #ifdef CACHE
  326.    memset ((char *) etab[0], 0, sizeof(struct etable)*(size_t)ETABLE);
  327.    memset ((char *) etab[1], 0, sizeof(struct etable)*(size_t)ETABLE);
  328. #endif
  329. #ifdef notdef
  330.    register unsigned int a;
  331.    for (a = 0; a < ttblsize + (unsigned int)rehash; a++)
  332.      {
  333.        ttable[black][a].depth = 0;
  334.        ttable[white][a].depth = 0;
  335.      }
  336. #endif
  337.     TTadd = 0; 
  338. }
  339.  
  340. #ifdef HASHFILE
  341. int Fbdcmp(unsigned char *a,unsigned char *b)
  342. {
  343.     register int i;
  344.     for(i = 0; i < PTBLBDSIZE; i++)
  345.         if(a[i] != b[i]) return false;
  346.     return true;
  347. }
  348. int
  349. ProbeFTable (short int side,
  350.          short int depth,
  351.          short int ply,
  352.          short int *alpha,
  353.          short int *beta,
  354.          short int *score)
  355.  
  356. /*
  357.  * Look for the current board position in the persistent transposition table.
  358.  */
  359.  
  360. {
  361.   register short int i;
  362.   register unsigned long hashix;
  363.   struct fileentry new, t;
  364.  
  365.   hashix = ((side == black) ? (hashkey & 0xFFFFFFFE) : (hashkey | 1)) & filesz;
  366.  
  367.   for (i = 0; i < PTBLBDSIZE; i++)
  368.     new.bd[i] = CB (i);
  369.   new.flags = 0;
  370.   for (i = 0; i < frehash; i++)
  371.     {
  372.       fseek (hashfile,
  373.          sizeof (struct fileentry) * ((hashix + 2 * i) & (filesz)),
  374.          SEEK_SET);
  375.       fread (&t, sizeof (struct fileentry), 1, hashfile);
  376.       if (!t.depth) break;
  377.        if(!Fbdcmp(t.bd, new.bd)) continue;
  378.       if (((short int) t.depth >= depth) 
  379.       && (new.flags == (unsigned short)(t.flags & (kingcastle | queencastle))))
  380.     {
  381. #if !defined BAREBONES
  382.       FHashCnt++;
  383. #endif
  384.       PV = (t.f << 8) | t.t;
  385.       *score = (t.sh << 8) | t.sl;
  386.       /* adjust *score so moves to mate is from root */
  387.       if (*score > SCORE_LIMIT)
  388.         *score -= ply;
  389.       else if (*score < -SCORE_LIMIT)
  390.         *score += ply;
  391.       if (t.flags & truescore)
  392.         {
  393.           *beta = -((SCORE_LIMIT+1000)*2);
  394.         }
  395.       else if (t.flags & lowerbound)
  396.         {
  397.           if (*score > *alpha)
  398.         *alpha = *score - 1;
  399.         }
  400.       else if (t.flags & upperbound)
  401.         {
  402.           if (*score < *beta)
  403.         *beta = *score + 1;
  404.         }
  405.       return (true);
  406.     }
  407.     }
  408.   return (false);
  409. }
  410.  
  411. void
  412. PutInFTable (short int side,
  413.          short int score,
  414.          short int depth,
  415.          short int ply,
  416.          short int alpha,
  417.          short int beta,
  418.          short unsigned int f,
  419.          short unsigned int t)
  420.  
  421. /*
  422.  * Store the current board position in the persistent transposition table.
  423.  */
  424.  
  425. {
  426.   register unsigned short i;
  427.   register unsigned long hashix;
  428.   struct fileentry new, tmp;
  429.  
  430.   hashix = ((side == black) ? (hashkey & 0xFFFFFFFE) : (hashkey | 1)) & filesz;
  431.   for (i = 0; i < PTBLBDSIZE; i++) 
  432.     new.bd[i] = CB (i);
  433.   new.f = (unsigned char) f;
  434.   new.t = (unsigned char) t;
  435.   if (score < alpha)
  436.     new.flags = upperbound;
  437.   else
  438.     new.flags = ((score > beta) ? lowerbound : truescore);
  439.   new.depth = (unsigned char) depth;
  440.   /* adjust *score so moves to mate is from root */
  441.   if (score > SCORE_LIMIT)
  442.     score += ply;
  443.   else if (score < -SCORE_LIMIT)
  444.     score -= ply;
  445.  
  446.  
  447.   new.sh = (unsigned char) (score >> 8);
  448.   new.sl = (unsigned char) (score & 0xFF);
  449.  
  450.   for (i = 0; i < frehash; i++)
  451.     {
  452.       fseek (hashfile,
  453.          sizeof (struct fileentry) * ((hashix + 2 * i) & (filesz)),
  454.          SEEK_SET);
  455.       if ( !fread (&tmp, sizeof (struct fileentry), 1, hashfile) )
  456.         {perror("hashfile");exit(1);}
  457.       if (tmp.depth && !Fbdcmp(tmp.bd,new.bd))continue;
  458.       if (tmp.depth == depth) break;
  459.       if (!tmp.depth || (short) tmp.depth < depth)
  460.     {
  461.       fseek (hashfile,
  462.          sizeof (struct fileentry) * ((hashix + 2 * i) & (filesz)),
  463.          SEEK_SET);
  464. #ifdef DEBUG4
  465.           if (debuglevel & 32)
  466.             {
  467.           printf ("-fadd\n");
  468.         }
  469. #endif
  470.       fwrite (&new, sizeof (struct fileentry), 1, hashfile);
  471. #if !defined BAREBONES
  472.           FHashAdd++;
  473. #endif
  474.       break;
  475.     }
  476.     }
  477. }
  478.  
  479. #endif /* HASHFILE */
  480. #endif /* ttblsz */
  481.  
  482. void
  483. ZeroRPT (void)
  484. {
  485. #ifdef NOMEMSET
  486.   register int side, i;
  487.   for (side = black; side <= white; side++)
  488.     for (i = 0; i < 256;)
  489.       rpthash[side][i++] = 0;
  490. #else
  491.    memset ((char *) rpthash, 0, sizeof (rpthash));
  492. #endif
  493. }
  494.  
  495.  
  496.  
  497.  
  498. #if defined CACHE
  499.  
  500. void
  501. PutInEETable (short int side,int score)
  502.  
  503. /*
  504.  * Store the current eval position in the transposition table.
  505.  */
  506.  
  507. {
  508.     register struct etable *ptbl;
  509.     ptbl = &(*etab[side])[hashkey & (ETABLE - 1)];
  510.     if (ptbl->ehashbd == hashbd) return;
  511. #if defined CACHETEST
  512.     { short i;
  513.       for (i = 0; i < PTBLBDSIZE; i++)
  514.     {
  515.       ptbl->bd[i] = CB (i);
  516.     }
  517.     }
  518. #endif /* CACHETEST */
  519.     ptbl->ehashbd = hashbd;
  520.     ptbl->escore[black] = pscore[black];
  521.     ptbl->escore[white] = pscore[white];
  522.     ptbl->hung[black] = hung[black];
  523.     ptbl->hung[white] = hung[white];
  524.     ptbl->score = score;
  525.     bcopy (svalue, &(ptbl->sscore), sizeof (svalue));
  526. #if !defined BAREBONES
  527.     EADD++;
  528. #endif
  529.     return;
  530. }
  531.  
  532.  
  533. int
  534. CheckEETable (short int side)
  535.  
  536. /* Get an evaluation from the transposition table */
  537. {
  538.     register struct etable *ptbl;
  539.     ptbl = &(*etab[side])[hashkey & (ETABLE - 1)];
  540.     if (hashbd == ptbl->ehashbd) 
  541.       {
  542.         return true;
  543.       }
  544.     return false;
  545. }
  546.  
  547.  
  548. int
  549. ProbeEETable (short int side, short int *score)
  550.  
  551. /* Get an evaluation from the transposition table */
  552. {
  553.     register struct etable *ptbl;
  554.     ptbl = &(*etab[side])[hashkey & (ETABLE - 1)];
  555.     if (hashbd == ptbl->ehashbd)
  556.       {
  557. #if defined CACHETEST
  558.     short i;
  559.         for (i = 0; i < PTBLBDSIZE; i++)
  560.       {
  561.         if (ptbl->bd[i] != CB (i))
  562.           {
  563. #if !defined BAREBONES
  564.             ShowMessage ("eetable probe collision detected");
  565. #endif
  566. #if DEBUG            
  567.         ShowBD(ptbl->bd);
  568. #endif
  569.             return false;
  570.           }
  571.       }
  572. #endif /* CACHETEST */ 
  573.       pscore[black] = ptbl->escore[black];
  574.       pscore[white] = ptbl->escore[white];
  575.       bcopy (&(ptbl->sscore), svalue, sizeof (svalue));
  576.       *score = ptbl->score;
  577.           hung[black] = ptbl->hung[black];
  578.           hung[white] = ptbl->hung[white];
  579. #if !defined BAREBONES
  580.       EGET++;
  581. #endif
  582.       return true;
  583.       }
  584.     return false;
  585.  
  586. }
  587.  
  588.  
  589. #endif /* CACHE */ 
  590.  
  591.  
  592.  
  593.  
  594.